package com.xg.frame.log;

import com.xg.sys.entity.SysLog;
import com.xg.sys.entity.SysUser;
import com.xg.sys.service.SysLogService;
import com.xg.frame.constant.SysConstant;
import com.xg.frame.entity.R;
import com.xg.frame.log.annotation.LogAnnotation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 日志最外层切面，保存日志
 * @author dehuisun
 *
 */
@Component
@Slf4j
@Aspect
@Order(-1) // 保证该AOP在@Transactional之前执行
public class LogAOP {

	@Autowired
    SysLogService sysLogService;

	private String loginUrl="com.xg.sys.controller.LoginController/login";

	@Around("@annotation(ds)")
	public Object logSave(ProceedingJoinPoint joinPoint, LogAnnotation ds) throws Throwable {
		Object result=null;
		// 请求开始时间
		long start = System.currentTimeMillis();
		String status="";
		try {
			result = joinPoint.proceed();
			status = SysConstant.STATE_Y;
		} catch (Exception e) {
			status = SysConstant.STATE_N;
			// 业务代码异常抛出，交由统一异常处理
			throw e;
		} finally {
			try{
				saveLog(joinPoint,ds,result,start,status);
			}catch (Exception e) {
				log.error("注解记录日志失败！", e);
			}
		}
        return result;
	}
	//保存日志
	private void saveLog(ProceedingJoinPoint joinPoint, LogAnnotation ds,Object result,long start,String status) throws Exception{
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
		LogAnnotation logAnnotation = methodSignature.getMethod().getDeclaredAnnotation(LogAnnotation.class);
		String url =  methodSignature.getDeclaringTypeName() + "/"+ methodSignature.getName();
		String ip=request.getRemoteAddr();
		SysLog sysLog=new SysLog();
		SysUser user = null;
		if(loginUrl.equals(url)){//登录处理
			R r= (R) result;
			if(r.isSuccess()&&r.getInfo()!=null) {
				user = new SysUser();
				user.setId((Long) r.getInfo());
			}
		}else{
			user = (SysUser) SecurityUtils.getSubject().getPrincipal();
		}
		long time=System.currentTimeMillis() - start;

		sysLog.setCreateUserId(user == null ? null : user.getId());
		sysLog.setTimes(String.valueOf(time));
		sysLog.setStatus(status);
		sysLog.setMethods(url);
		sysLog.setMethodsName(logAnnotation.describe());
		sysLog.setUserIp(ip);
		sysLogService.save(sysLog);
	}

}
